package entradasalida;

import java.awt.Frame;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

import Jama.Matrix;
import algoritmos.Matriz;

public class EntradaFicheroNumerico {
	protected ArrayList<Matrix> entrada;
	
	protected ArrayList<Matrix> centros;
	
	protected ArrayList<Integer> limites;
	
	protected int dimension;
	
	/**
	 * Fichero del que se obtendrán los datos de entrada
	 */
	private File fichero;
	
	/**
	 * Constructor por defecto
	 */
	public EntradaFicheroNumerico(){
	}
	
	/**
	 * Constructor de la clase
	 * @param arg0 Frame llamante
	 */
	public EntradaFicheroNumerico(Frame arg0){
		entrada = new ArrayList<Matrix>();
		centros = new ArrayList<Matrix>();
		limites = new ArrayList<Integer>();
		JFileChooser f = new JFileChooser(System.getProperty("user.dir"));
		FileNameExtensionFilter filtro = new FileNameExtensionFilter("Ficheros de datos","txt");
		f.setFileFilter(filtro);
		int returnVal = f.showOpenDialog(arg0);
		if(returnVal == JFileChooser.APPROVE_OPTION) {
			fichero = f.getSelectedFile();
		} else {
			fichero = null;
		}
		if (fichero != null){
			LeeDatosFichero();
		}
	}
	
	/**
	 * Lee el fichero y adapta las estructuras utilizadas en memoria
	 */
	private void LeeDatosFichero(){
		try {
			char buffer[] = new char[1];
			FileReader rd = new FileReader(fichero);
			while (rd.read(buffer) != -1){
				if (buffer[0] == '#' || buffer[0] == ' ') // Comentario o linea vacía
					while (buffer[0] != '\n'){
						rd.read(buffer);
					}
				else { // Línea con dato
					if (buffer[0] == 'd'){ // Dimensión de los datos
						rd.read(buffer);
						while (buffer[0] != '='){
							rd.read(buffer);
						}
						rd.read(buffer);
						while (buffer[0] == ' '){
							rd.read(buffer);
						}
						while(buffer[0] != '\n'){
							int temp = 0;
							while (buffer[0] != ',' && buffer[0] != ' ' && buffer[0] != '\n'){
								temp *= 10;
								temp += buffer[0] - '0';
								rd.read(buffer);
							}
							dimension = temp;
							if (buffer[0] != '\n') rd.read(buffer);
						}	
					}else if (buffer[0] == 'c'){
						rd.read(buffer);
						// Centro de clase
						while (buffer[0] != '='){
							rd.read(buffer);
						}
						rd.read(buffer);
						while (buffer[0] == ' '){
							rd.read(buffer);
						}
						Matriz dato = new Matriz(1,dimension);
						int contador = 0;
						//ArrayList<Number> dato = new ArrayList<Number>();
						while(buffer[0] != '\n'){
							double temp = 0;
							while (buffer[0] != ',' && buffer[0] != ' ' && buffer[0] != '\n'){
								temp *= 10;
								temp += buffer[0] - '0';
								rd.read(buffer);
							}
							dato.set(0,contador,temp);
							contador++;
							if (buffer[0] != '\n') rd.read(buffer);
						}		
						centros.add(dato);
					}else if (buffer[0] == 'x'){ // Es un dato de entrada
						while (buffer[0] != '='){
							rd.read(buffer);
						}
						rd.read(buffer);
						while (buffer[0] == ' '){
							rd.read(buffer);
						}
						Matriz dato = new Matriz(1,dimension);
						int contador = 0;
						//ArrayList<Number> dato = new ArrayList<Number>();
						while(buffer[0] != '\n'){
							double temp = 0;
							while (buffer[0] != ',' && buffer[0] != ' ' && buffer[0] != '\n'){
								temp *= 10;
								temp += buffer[0] - '0';
								rd.read(buffer);
							}
							dato.set(0,contador,temp);
							contador++;
							if (buffer[0] != '\n') rd.read(buffer);
						}		
						entrada.add(dato);
					}else if (buffer[0] == 'l'){ // Es un límite de conjunto de datos
						while (buffer[0] != '='){
							rd.read(buffer);
						}
						rd.read(buffer);
						while (buffer[0] == ' '){
							rd.read(buffer);
						}
						while(buffer[0] != '\n'){
							int temp = 0;
							while (buffer[0] != ',' && buffer[0] != ' ' && buffer[0] != '\n'){
								temp *= 10;
								temp += buffer[0] - '0';
								rd.read(buffer);
							}
							limites.add(temp);
							if (buffer[0] != '\n') rd.read(buffer);
						}		
					}
				}
			}			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			System.out.println("Fichero "+ fichero.getName() + " leído correctamente.");
		}
		
	}

	/*=========================================================================*
	 *							Accesores y mutadores                          * 
	 *=========================================================================*/

	public ArrayList<Matrix> getEntrada() {
		return entrada;
	}

	public void setEntrada(ArrayList<Matrix> entrada) {
		this.entrada = entrada;
	}

	public ArrayList<Matrix> getCentros() {
		return centros;
	}

	public void setCentros(ArrayList<Matrix> centros) {
		this.centros = centros;
	}

	public ArrayList<Integer> getLimites() {
		return limites;
	}

	public void setLimites(ArrayList<Integer> limites) {
		this.limites = limites;
	}

	public File getFichero() {
		return fichero;
	}
	
	
	/*
	 * Ejemplo de fichero de entrada:
	 * 
	 * # Comentario
	 * 
	 * d = 3
	 * 
	 * x1 = 5,6,4
	 * x2 = 1,2,5
	 * x3 = 10,20,30
	 * # Tantas entradas como se desee
	 * 
	 * c1 = 1,2,3
	 * c2 = 5,10,5
	 * # Tantos centros como se desee
	 * 
	 * l1 = 3
	 * l2 = 5
	 * # Tantos límites para algoritmo paramétrico como se desee
	 * 
	 */
}
